package com.beigai.imessage.message.service;

import com.beigai.imessage.common.except.MessageException;
import com.beigai.imessage.dao.mapper.ext.MessageOfflinePOMapperExt;
import com.beigai.imessage.dao.po.MessageOfflinePO;
import com.beigai.imessage.message.dto.*;
import com.beigai.imessage.message.handler.IMessageHandler;
import com.beigai.imessage.message.handler.ImageMessageHandler;
import com.beigai.imessage.message.handler.StrMessageHandler;
import com.beigai.imessage.message.queue.MemoryPriorityQueue;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by xxl on 2017/5/16.
 */
@Service
public class MemoryMessageService implements MessageService {

    @Resource(type = ImageMessageHandler.class)
    private IMessageHandler imageMessageHandler;

    @Resource(type = StrMessageHandler.class)
    private IMessageHandler strMessageHandler;

    @Autowired
    private MessageOfflinePOMapperExt messageOfflinePOMapperExt;

    @Override
    public MSendResp sendMessageOnline(MSendReq mSendReq) throws MessageException {
        MessageUnit messageUnit = new MessageUnit();
        BeanUtils.copyProperties(mSendReq, messageUnit);
        MessageDTO messageDTO = handMessage(messageUnit);
        MemoryPriorityQueue.sendMessage(generatorKey(mSendReq.getUserCode(), mSendReq.getMessageToCode()), messageDTO);
        return new MSendResp(MSendResp.SUCCESS);
    }

    @Override
    public MSendResp sendMessageOffline(MSendReq mSendReq) {
        MessageOfflinePO record = new MessageOfflinePO();
        BeanUtils.copyProperties(mSendReq, record);
        record.setMessageFromCode(mSendReq.getUserCode());
        int READY=0;
        record.setStatus(READY);
        messageOfflinePOMapperExt.insertSelective(record);
        return new MSendResp(MSendResp.SUCCESS);
    }

    @Override
    public MRecResp receiveMessageOnline(MRecReq mRecReq) {
        List<MessageDTO> messageDTOS = new ArrayList<MessageDTO>();
        while (true) {
            MessageDTO messageDTO = MemoryPriorityQueue.receiveMessage(generatorKey(mRecReq.getMessageFromCode(), mRecReq.getUserCode()));
            if (messageDTO != null) {
                MessageDTO mRecResp = new MessageDTO();
                BeanUtils.copyProperties(messageDTO, mRecResp);
                messageDTOS.add(mRecResp);
            } else
                break;
        }
        MRecResp mRecResp = new MRecResp();
        mRecResp.setMessageDTOS(messageDTOS);
        return mRecResp;
    }

    @Override
    public MRecResp receiveMessageOffline(MRecReq mRecReq) throws MessageException {
        List<MessageDTO> messageDTOS = new ArrayList<MessageDTO>();
        List<MessageUnit> messages = messageOfflinePOMapperExt.queryByConditions(mRecReq);
        for (MessageUnit message : messages) {
            MessageDTO messageDTO = handMessage(message);
            if (messageDTO != null) {
                messageDTOS.add(messageDTO);
            }
        }
        MRecResp mRecResp = new MRecResp();
        mRecResp.setMessageDTOS(messageDTOS);
        return mRecResp;
    }

    private MessageDTO handMessage(MessageUnit message) throws MessageException {
        MessageDTO messageDTO;
        switch (message.getMessageType()) {
            case MessageUnit.STR:
                messageDTO = strMessageHandler.getMessage(message);
                break;
            case MessageUnit.IMAGE:
                messageDTO = imageMessageHandler.getMessage(message);
                break;
            default:
                throw new MessageException(MessageException.UNKNOWMESSAGETYPE, "未知消息类型");
        }
        return messageDTO;
    }

    public static final String QPREFIX = "q_";

    private String generatorKey(String fromCode, String toCode) {
        return QPREFIX + fromCode + toCode;
    }
}
